
const webpack = require('webpack');
const {join} = require('path');
const merge = require('webpack-merge'); // 合并webpack配置插件
const argv = require('yargs-parser')(process.argv.slice(2)); // 可以解析参数成对象，也可以读取到webpack系统变量
const _mode = argv.mode || 'development'; // 通过argv插件读取webpack环境变量，默认开发环境
const _mergeConfig = require(`./config/webpack.${_mode}.js`); // 加载适合环境的配置
const _modeflag = (_mode == 'production' ? true : false); // 判断是否线上环境，用于配置参数

const HtmlWebpackPlugin = require('html-webpack-plugin'); // 生成解析html页面
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // 引入分离打包CSS

// 配置webpack选项
let config = {
  entry: { // 入口文件
    app: "./src/app"
  },
  // 配置优化选项，从4版本中默认配置好了一些参数的
  optimization: {
    // 把公用JS文件分组
    splitChunks: {
      cacheGroups:{
        // 创建不同分组的名称，配置不同的规则
        common: {
          chunks: "initial", // 默认都抽取出来,只对入口文件处理
          name: "common", // 生成的文件名称,html引入组件就引此名称
          minChunks: 6, // 最少引用几次就打包到此文件内
          priority: 10,  //优先级，一个chunk很可能满足多个缓存组，会被抽取到优先级高的缓存组中
          enforce: true  // 如果cacheGroup中没有设置minSize，则据此判断是否使用上层的minSize，true：则使用0，false：使用上层minSize
        }
      }
    },
    // 单独把runtime核心包提取成一个单独文件，放入页面（webpack运行时核心文件）
    runtimeChunk: {
      name: "runtime"
    },
  },
  module: {
    rules: [
      /* 解析css,并不生成CSS */
      {
        test: /\.css$/,
        use: [{
            loader: MiniCssExtractPlugin.loader,
            options: {
              minimize: _modeflag, // 是否启用压缩
              publicPath: '/' // 插入到页面 文件路径前缀
            }
          },
          'css-loader',
          'postcss-loader',
        ]
      },
      // tsx文件解析使用ts-loader
      { test: /\.tsx?$/, loader: "ts-loader",options: {
        transpileOnly: true
      }},
      // 把js错误映射到TS源文件中去
      { enforce: "pre", test: /\.js$/, loader: "source-map-loader" },
      {/* 解析图片-放到指定img路径 */
        test: /\.(jpg|jpeg|png|gif)\??.*$/,
        use: [{
          loader: 'url-loader',
          options: {
            limit: 8192, // 小于8KB都会转换成base64代码
            name: 'resources/[name].[ext]'
          }
        }]
      },
      /* 字体文件加载器-放到指定路径,大于8kb才生成文件 */
      {test: /\.(woff|woff2|ttf|otf|svg|eot)\??.*$/,
        use: [{
          loader: 'url-loader',
          options: {
            limit: 8192,
            name: 'resources/fonts/[name].[ext]'
          }
        }]
      },
    ]
  },
  watch: !_modeflag, // 监听文件变化，如有变动实时编译
  plugins: [
    // 生成HTML插件，指定HTML模板文件
    new HtmlWebpackPlugin({
      template: join(__dirname, './src/index.template.html'), // html模板文件路径
      inject: true
    }),
    // 输出CSS文件
    new MiniCssExtractPlugin({
      filename: _modeflag ? "css/[name].[contenthash:5].css" : "css/[name].css",
      chunkFilename: _modeflag ? "css/[name].[contenthash:5].css" : "css/[name].css"
    }),

  ],

  resolve: {
    // 指定文件后缀名，这样导入模块文件就不用写后续，从左至右顺序读取
    extensions: [".ts", ".tsx", ".js", ".json"],
    // 在模块中添加 src, 当你导入文件时，可以将 src 作为相关路径
    modules: ['src', 'node_modules'],
  },

};

module.exports = merge( _mergeConfig,config); // 合并配置文件输出
